package jmine.tec.hydra.dao;

import java.util.List;

import jmine.tec.hydra.HydraController;
import jmine.tec.hydra.api.HydraSpecification;
import jmine.tec.hydra.domain.message.HydraConversation;

import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BeanNotFoundException;

/**
 * @author piercio
 */
public class HydraConversationDAO extends BaseDAO<HydraConversation> {

    /**
     * Cria uma nova conversa, com a identificação/mnemonico e para o dado sistema, que contém as mensagens recebidas com essa
     * identificação. Essas mensagens são geradas quando se recebe uma mensagem sem envio prévio, mas que tenham algum tipo de identificação
     * (mnemonico).
     * 
     * @param specification especificação a qual a conversa segue.
     * @param mnemonico o mnemonico da conversa.
     * @return uma conversa única para o sistema.
     */
    public HydraConversation findOrCreateConversation(HydraSpecification specification, String mnemonico) {
        try {
            HydraConversation conversation = this.findByNaturalKey(mnemonico);
            return conversation;
        } catch (BeanNotFoundException e) {
            HydraConversation conversation = this.createBean();
            conversation.setMnemonico(mnemonico);
            conversation.setSpecification(specification);
            return conversation;
        }
    }

    /**
     * Cria uma nova conversa com identificação única gerada pelo sistema.
     * 
     * @param specification especificação a qual a conversa segue.
     * @return a conversa nova.
     */
    public HydraConversation createUniqueConversation(HydraSpecification specification) {
        HydraConversation conversation = this.createBean();
        conversation.setMnemonico(((HydraController) this.controller).createIdentification());
        conversation.setSpecification(specification);
        conversation.getPersister().save();
        return conversation;
    }

    /**
     * Retorna uma lista de {@link HydraConversation}, de acordo com a {@link HydraSpecification} passada como parametro.
     * 
     * @param specification especificação a qual a conversa segue.
     * @return lista de conversations.
     */
    public List<HydraConversation> findBySpecification(HydraSpecification specification) {
        Criteria crit = this.createCriteria();
        crit.add(Restrictions.eq("specification", specification));
        return this.executeQuery(crit);
    }

}
